home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
admin
/
linuxcon.000
/
linuxcon
/
linuxconf-1.6
/
mailconf
/
mtable.c
< prev
Wrap
C/C++ Source or Header
|
1996-07-01
|
6KB
|
275 lines
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "internal.h"
#include "../netconf/netconf.h"
#include "../paths.h"
#include "mailconf.h"
#include "mailconf.m"
static MAILCONF_HELP_FILE help_mailtable ("mailtable");
static CONFIG_FILE f_mailtable (VAR_LIB_MAILERTABLE,help_mailtable
,CONFIGF_MANAGED|CONFIGF_OPTIONNAL);
PUBLIC SPC_ROUTE::SPC_ROUTE()
{
subdomain = 0;
}
PUBLIC void SPC_ROUTE::write (FILE *fout)
{
fprintf (fout,"%s %s:%s\n",to.get(),mailer.get(),forwarder.get());
if (subdomain){
fprintf (fout,".%s %s:%s\n",to.get(),mailer.get()
,forwarder.get());
}
}
/*
Edit one routing and return 0 if edit was success
Return 1 if the entry must be deleted.
*/
PUBLIC int SPC_ROUTE::edit()
{
DIALOG dia;
dia.newf_str (MSG_U(F_DEST,"Destination"),to);
dia.newf_str (MSG_U(F_FORWARD,"Forwader"),forwarder);
dia.newf_chk ("",subdomain,MSG_U(F_MANAGE,"Manage sub-domain identically"));
FIELD_COMBO *com = dia.newf_combo (MSG_U(F_MAILER,"Mailer"),mailer);
basic_setmailer (com);
int ret = -1;
int nof = 0;
while (1){
MENU_STATUS code = dia.edit (MSG_U(T_SPECIAL,"Special routing")
,MSG_U(I_SPECIAL
,"Enter a destination (host) and the\n"
"forwarder (another host) used to reach it\n"
"and the mailer (transport) needed")
,help_mailtable.getpath()
,nof
,MENUBUT_DEL|MENUBUT_ACCEPT|MENUBUT_CANCEL);
if (code == MENU_CANCEL || code == MENU_ESCAPE){
break;
}else if (code == MENU_DEL){
ret = 1;
break;
}else{
if (to.is_empty()
|| forwarder.is_empty()
|| mailer.is_empty()){
xconf_error (MSG_U(E_EMPTYF,"All field must be filled"));
}else{
ret = 0;
break;
}
}
}
if (ret != 0) dia.restore();
return ret;
}
PUBLIC SPC_ROUTES::SPC_ROUTES()
{
/* #Specification: mailconf / special routing
A lookup file may be used by sendmail to managed
the routing of certain site. This file is called
the mailer table. Mostly, if the destination
match one entry of this table, the value pair
mailer:forwarder will be used.
This ascii file must be turned into a database so
sendmail can use it efficiently. This is normally
done using the makemap utility.
mailconf will always generate this file even if it
is empty. One reason is to simplify the generation
of the sendmail.cf file.
*/
FILE *fin = f_mailtable.fopen ("r");
if (fin != NULL){
char buf[500];
int noline = 0;
while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
noline++;
strip_end (buf);
char *pt = str_skip (buf);
if (pt[0] != '\0'){
char word[300];
pt = str_copyword(word,pt);
SPC_ROUTE *rt = new SPC_ROUTE;
rt->to.setfrom (word);
pt = str_skip(pt);
if (pt[0] != '\0'){
str_copyword(word,pt);
pt = strchr(word,':');
if (pt != NULL){
*pt++ = '\0';
rt->mailer.setfrom(word);
rt->forwarder.setfrom(pt);
add (rt);
}
}
}
}
fclose (fin);
/* #Specification: mailconf / mailertable / domain and subdomain
We can specify a different special routing for a
domain, and for subdomain in the mailer table.
This is done with two separate line:
#
foo.com mailer:forwarder
.foo.com mailer:forwarder
#
The first line manage foo.com and the other
everything else under it.
mailconf present this information in a single
record. A checkbox let specify if we want to
manage the subdomain identically. This is
simpler to understand for administrator.
The information is still written as two separate
line in the mailertable and fold back into
a single one when read
*/
for (int i=0; i<getnb(); i++){
SPC_ROUTE *rt = getitem(i);
const char *to = rt->to.get();
if (to[0] != '.'){
for (int j=0; j<getnb(); j++){
SPC_ROUTE *rtf = getitem(j);
const char *tof = rtf->to.get();
if (tof[0] == '.'
&& strcmp(to,tof+1)==0
&& rt->mailer.cmp(rtf->mailer)==0
&& rt->forwarder.cmp(rtf->forwarder)==0){
// Ok, we have found the same record, but applying
// to subdomain.
// We set the subdomain flag in rt and delete
// this record
rt->subdomain = 1;
remove_del (rtf);
if (j < i) i--;
break;
}
}
}
}
}
}
/*
Write the mailertable back.
*/
PUBLIC int SPC_ROUTES::save()
{
int ret = -1;
FILE *fout = f_mailtable.fopen ("w");
if (fout != NULL){
int nb = getnb();
for (int i=0; i<nb; i++) getitem(i)->write(fout);
fclose (fout);
}
return ret;
}
/*
Write the mailertable back and rebuild the database
*/
PUBLIC int SPC_ROUTES::build(
const char *dbformat) // Format to used (btree, dbm)
// If NULL, won't rebuild the database
{
int ret = -1;
if (dbformat != NULL){
// This save simply insure that the file exist
// The constructor of SPC_ROUTES will manage a missing
// mailertable as an empty one. Given that the sendmail.cf
// refer to it all the time, we force a generation of the file
save();
char buf[300];
sprintf (buf,"%s %s <%s"
,dbformat
,f_mailtable.getpath()
,f_mailtable.getpath());
ret = netconf_system_if ("makemap",buf);
}
return ret;
}
PUBLIC SPC_ROUTE *SPC_ROUTES::getitem(int no)
{
return (SPC_ROUTE *)ARRAY::getitem(no);
}
static int cmp(const ARRAY_OBJ *p1, const ARRAY_OBJ *p2)
{
SPC_ROUTE *r1 = (SPC_ROUTE *)p1;
SPC_ROUTE *r2 = (SPC_ROUTE *)p2;
return r1->to.cmp(r2->to);
}
PUBLIC void SPC_ROUTES::sort()
{
ARRAY::sort (cmp);
}
/*
Edit the special routings database.
Return 0 if the something was changed in the database.
*/
PUBLIC int SPC_ROUTES::edit ()
{
int ret = -1;
while (1){
sort();
int nb = getnb();
MENU_STATUS code;
int choice = 0;
{
DIALOG dia;
for (int i=0; i<nb; i++){
SPC_ROUTE *rt = getitem(i);
dia.new_menuitem (" ",rt->to.get());
}
dia.addwhat (MSG_U(I_ADDONE,"one routing spec"));
code = dia.editmenu (
MSG_U(T_SPECIALS,"Special routings")
,MSG_U(I_SPECIALS,"You are allowed to edit/add/remove routings\n")
,help_mailtable
,choice
,MENUBUT_ADD);
}
if (code == MENU_QUIT || code == MENU_ESCAPE){
break;
}else if (code == MENU_ADD){
SPC_ROUTE *spc = new SPC_ROUTE;
if (spc->edit()==0){
add (spc);
save();
ret = 0;
}else{
delete spc;
}
}else if (nb > 0){
SPC_ROUTE *spc = getitem(choice);
int status = spc->edit();
if (status != -1){
if (status == 1) remove_del(spc);
save();
ret = 0;
}
}
}
return ret;
}